/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. **/
package com.minierp.service.impl;

import com.minierp.bean.InBillBean;
import com.minierp.bean.InBillItemBean;
import com.minierp.bean.UserBean;
import com.minierp.dao.BusinessBillDao;
import com.minierp.dao.IdGenerator;
import com.minierp.dao.InBillDao;
import com.minierp.dao.InBillItemDao;
import com.minierp.dao.SerialNumberDao;
import com.minierp.dao.StockBalanceDao;
import com.minierp.dao.StockDao;
import com.minierp.err.DataChangedException;
import com.minierp.err.NotAllowException;
import com.minierp.err.StockNoEnoughException;
import com.minierp.helper.PageHelper;
import com.minierp.model.BusinessBill;
import com.minierp.model.BusinessBillExt;
import com.minierp.model.BusinessProfit;
import com.minierp.model.InBill;
import com.minierp.model.InBillItem;
import com.minierp.model.InOutHistory;
import com.minierp.model.Stock;
import com.minierp.model.SystemLog;
import com.minierp.service.InBillService;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class InBillServiceImpl implements InBillService {
	public void txInsert(InBillBean form, InBillDao inBillDao,
			InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, SerialNumberDao serialNumberDao,
			BusinessBillDao businessBillDao, IdGenerator idGenerator)
			throws Exception {
		InBill obj = form.getInBill();
		obj.setCreateTime(new Date());
		obj.setId(idGenerator.getId(InBill.class.getName()));
		if (!form.getCodeRule().getGenerateRule().equals("MANUAL")) {
			obj.setBillCode(PageHelper.generateCode(serialNumberDao,
					form.getCodeRule(), "", form.getInBill().getTallySetId()));

			for (InBill updateStock = inBillDao.get(obj.getBillCode()); updateStock != null; updateStock = inBillDao
					.get(obj.getBillCode())) {
				obj.setBillCode(PageHelper.generateCode(serialNumberDao, form
						.getCodeRule(), "", form.getInBill().getTallySetId()));
			}
		}

		this.setCost(form);
		boolean updateStock1 = false;
		if (obj.getExamined().equals("Y")) {
			obj.setExamineTime(new Date());
			updateStock1 = true;
		}

		inBillDao.save(obj);
		this.saveItems(obj, updateStock1, form.getOffererName(),
				form.getItems(), inBillItemDao, stockDao, stockBalanceDao,
				idGenerator);
		if (obj.getExamined().equals("Y")) {
			this.updateBusinessProfit("ADD", obj.getBusinessBillCode(),
					this.getInCost(form.getItems()), businessBillDao,
					idGenerator);
		}

	}

	private void setCost(InBillBean form) {
		List items = form.getItems();

		for (int i = 0; i < items.size(); ++i) {
			InBillItemBean bean = (InBillItemBean) items.get(i);
			if (!bean.getStatus().equals("DELETE")) {
				bean.getInBillItem().setCost(
						bean.getInBillItem().getAmount()
								.multiply(bean.getInBillItem().getUnitPrice())
								.setScale(2, 4));
			}
		}

	}

	private BigDecimal getInCost(List<?> itemBeanList) {
		BigDecimal inCost = new BigDecimal(0);

		for (int i = 0; i < itemBeanList.size(); ++i) {
			InBillItemBean bean = (InBillItemBean) itemBeanList.get(i);
			if (!bean.getStatus().equals("DELETE")) {
				inCost = inCost.add(bean.getInBillItem().getCost());
			}
		}

		return inCost;
	}

	private void updateBusinessProfit(String countType, String bbCode,
			BigDecimal inCost, BusinessBillDao businessBillDao,
			IdGenerator idGenerator) {
		if (bbCode != null && !bbCode.equals("")) {
			BusinessBill bb = businessBillDao.get(bbCode);
			if (bb != null) {
				BusinessBillExt be = (BusinessBillExt) businessBillDao.get(
						BusinessBillExt.class, bb.getId());
				BusinessProfit p = businessBillDao.getBusinessProfit(bbCode);
				if (p == null) {
					p = new BusinessProfit();
					p.setBbCode(bbCode);
					p.setId(idGenerator.getId(BusinessProfit.class.getName()));
					p.setCooperCost(new BigDecimal(0));
					p.setFeeCost(new BigDecimal(0));
					if (countType.equals("ADD")) {
						p.setMaterialCost((new BigDecimal(0)).subtract(inCost));
					} else {
						p.setMaterialCost(inCost);
					}

					p.setProfitCost(bb.getCost().add(be.getAdjustCost())
							.subtract(p.getMaterialCost()));
					businessBillDao.save(p);
				} else {
					if (countType.equals("ADD")) {
						p.setMaterialCost(p.getMaterialCost().subtract(inCost));
						p.setProfitCost(p.getProfitCost().add(inCost));
					} else {
						p.setMaterialCost(p.getMaterialCost().add(inCost));
						p.setProfitCost(p.getProfitCost().subtract(inCost));
					}

					businessBillDao.update(p);
				}
			}
		}

	}

	public void txUpdate(InBillBean form, InBillDao inBillDao,
			InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, BusinessBillDao businessBillDao,
			IdGenerator idGenerator) throws Exception {
		InBill obj = form.getInBill();
		Object[] sv = inBillDao.getStatusValues(obj.getId());
		if (sv == null) {
			throw new Exception("Can\'t get status values for in bill:"
					+ obj.getId());
		} else {
			long existSycVal = ((Date) sv[0]).getTime();
			String exitEnabled = sv[1].toString();
			String existExamined = sv[2].toString();
			if (existSycVal != form.getSychronizeValue()) {
				throw new DataChangedException("入库单已被其他操作修改，请关闭页面再打开后重新操作！");
			} else if (exitEnabled.equals("N")) {
				throw new NotAllowException("入库单已作废，不能修改！");
			} else if (existExamined.equals("Y")) {
				throw new NotAllowException("入库单已审核，不能修改！");
			} else {
				this.setCost(form);
				boolean updateStock = false;
				if (obj.getExamined().equals("Y")) {
					obj.setExamineTime(new Date());
					updateStock = true;
				}

				obj.setUpdateTime(new Date());
				inBillDao.update(obj);
				this.saveItems(obj, updateStock, form.getOffererName(),
						form.getItems(), inBillItemDao, stockDao,
						stockBalanceDao, idGenerator);
				if (obj.getExamined().equals("Y")) {
					this.updateBusinessProfit("ADD", obj.getBusinessBillCode(),
							this.getInCost(form.getItems()), businessBillDao,
							idGenerator);
				}

			}
		}
	}

	private void saveItems(InBill inBill, boolean updateStock, String offeName,
			List<?> items, InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator)
			throws StockNoEnoughException, ParseException {
		int newNum = 0;

		for (int curItemId = 0; curItemId < items.size(); ++curItemId) {
			InBillItemBean bean = (InBillItemBean) items.get(curItemId);
			if (bean.getStatus().equals("NEW")) {
				++newNum;
			}
		}

		long arg13 = 0L;
		if (newNum > 0) {
			arg13 = idGenerator.getId(InBillItem.class.getName(), newNum);
		}

		for (int i = 0; i < items.size(); ++i) {
			InBillItemBean bean1 = (InBillItemBean) items.get(i);
			bean1.getInBillItem().setBillId(inBill.getId());
			if (bean1.getStatus().equals("DELETE")) {
				if (bean1.getInBillItem().getId() != 0L) {
					inBillItemDao.delete(bean1.getInBillItem().getId());
				}
			} else if (bean1.getStatus().equals("EDIT")) {
				inBillItemDao.update(bean1.getInBillItem());
			} else if (bean1.getStatus().equals("NEW")) {
				bean1.getInBillItem().setId(arg13);
				inBillItemDao.save(bean1.getInBillItem());
				++arg13;
			}
		}

		if (updateStock) {
			this.updateStock(inBill, inBillItemDao, stockDao, stockBalanceDao,
					idGenerator, offeName, "SAVE_EXAM", "");
		}

	}

	private void updateStock(InBill b, InBillItemDao inBillItemDao,
			StockDao stockDao, StockBalanceDao stockBalanceDao,
			IdGenerator idGenerator, String requName, String operType,
			String stafName) throws StockNoEnoughException, ParseException {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		BigDecimal zero = new BigDecimal(0);
		List items = inBillItemDao.getList(b.getId());

		for (int j = 0; j < items.size(); ++j) {
			InBillItem it = (InBillItem) items.get(j);
			BigDecimal iohUp = it.getUnitPrice();
			BigDecimal iohAmount;
			BigDecimal iohCost;
			if (!operType.equals("SAVE_EXAM") && !operType.equals("EXAM")) {
				iohAmount = zero.subtract(it.getAmount());
				iohCost = zero.subtract(it.getCost());
			} else {
				iohAmount = it.getAmount();
				iohCost = it.getCost();
			}

			Stock s = stockDao.get(it.getProductId(), b.getStorehouseId());
			BigDecimal currentAmount;
			if (s == null) {
				currentAmount = new BigDecimal(0);
				s = new Stock();
				s.setAmount(iohAmount);
				s.setCost(iohCost);
				s.setUnitPrice(iohUp);
				s.setId(idGenerator.getId(Stock.class.getName()));
				s.setProductId(it.getProductId());
				s.setStorehouseId(b.getStorehouseId());
				stockDao.save(s);
			} else {
				currentAmount = s.getAmount();
				s.setAmount(s.getAmount().add(iohAmount));
				s.setCost(s.getCost().add(iohCost));
				if (s.getAmount().compareTo(zero) != 0) {
					s.setUnitPrice(s.getCost().divide(s.getAmount(), 4, 4));
				}

				stockDao.update(s);
			}

			if (s.getAmount().compareTo(new BigDecimal(0)) == -1) {
				String arg19 = PageHelper.stockNotEnoughMeg(stockDao,
						it.getProductId(), currentAmount, s.getAmount());
				throw new StockNoEnoughException(arg19);
			}

			PageHelper.updateStockBalance(stockBalanceDao, it.getProductId(),
					iohAmount, b.getInDate(), iohCost, b.getStorehouseId(),
					idGenerator, "ADD");
			if (operType.equals("UN_EXAM") || operType.equals("CANC")) {
				stockDao.updateIohLogData("IN_BILL", b.getId());
			}

			InOutHistory h = new InOutHistory();
			h.setBillId(b.getId());
			h.setBillCode(b.getBillCode());
			h.setBillDate(b.getInDate());
			h.setProId(it.getProductId());
			h.setStoId(b.getStorehouseId());
			h.setBillType("IN_BILL");
			h.setId(idGenerator.getId(InOutHistory.class.getName()));
			h.setOperType(operType);
			h.setIoType("IN");
			h.setTypeId(b.getInTypeId());
			h.setRequType(b.getOffererType());
			h.setRequId(b.getOffererId());
			h.setRequName(requName);
			h.setUnitPrice(iohUp);
			h.setCost(iohCost);
			h.setAmount(iohAmount);
			h.setStorAmou(s.getAmount());
			h.setStorCost(s.getCost());
			h.setStorUp(s.getUnitPrice());
			h.setBbCode(b.getBusinessBillCode());
			if (operType.equals("UN_EXAM")) {
				h.setLogData("Y");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "反审核单据");
			} else if (operType.equals("CANC")) {
				h.setLogData("Y");
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "作废单据");
			} else {
				h.setLogData("N");
				h.setMark(it.getMark());
			}

			stockDao.save(h);
		}

	}

	public void txExamine(long id, InBillDao inBillDao,
			InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, BusinessBillDao businessBillDao,
			IdGenerator idGenerator, UserBean ub)
			throws StockNoEnoughException, ParseException {
		InBill b = (InBill) inBillDao.get(InBill.class, id);
		if (b != null && b.getEnabled().equals("Y")
				&& b.getExamined().equals("N")) {
			b.setExamined("Y");
			b.setExamineTime(new Date());
			b.setUpdateTime(new Date());
			b.setExaminerId(ub.getStaffer().getId());
			b.setExaminerName(ub.getStaffer().getStafferName());
			inBillDao.update(b);
			String offeName = PageHelper.getRequName(b.getOffererId(),
					b.getOffererType(), inBillDao);
			this.updateStock(b, inBillItemDao, stockDao, stockBalanceDao,
					idGenerator, offeName, "EXAM", "");
			List itemList = inBillItemDao.getList(b.getId());
			BigDecimal inCost = new BigDecimal(0);

			for (int j = 0; j < itemList.size(); ++j) {
				InBillItem item = (InBillItem) itemList.get(j);
				inCost = inCost.add(item.getCost());
			}

			this.updateBusinessProfit("ADD", b.getBusinessBillCode(), inCost,
					businessBillDao, idGenerator);
		}

	}

	public void txUnExamine(long id, InBillDao inBillDao,
			InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, BusinessBillDao businessBillDao,
			IdGenerator idGenerator, UserBean ub)
			throws StockNoEnoughException, ParseException {
		InBill b = (InBill) inBillDao.get(InBill.class, id);
		if (b != null && b.getEnabled().equals("Y")
				&& b.getExamined().equals("Y")) {
			b.setExamined("N");
			b.setUpdateTime(new Date());
			b.setExaminerId(0L);
			b.setExaminerName("");
			inBillDao.update(b);
			String offeName = PageHelper.getRequName(b.getOffererId(),
					b.getOffererType(), inBillDao);
			this.updateStock(b, inBillItemDao, stockDao, stockBalanceDao,
					idGenerator, offeName, "UN_EXAM", ub.getStaffer()
							.getStafferName());
			List itemList = inBillItemDao.getList(b.getId());
			BigDecimal inCost = new BigDecimal(0);

			for (int j = 0; j < itemList.size(); ++j) {
				InBillItem item = (InBillItem) itemList.get(j);
				inCost = inCost.add(item.getCost());
			}

			this.updateBusinessProfit("SUB", b.getBusinessBillCode(), inCost,
					businessBillDao, idGenerator);
		}

	}

	public void txCancel(long id, String reason, InBillDao inBillDao,
			InBillItemDao inBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, BusinessBillDao businessBillDao,
			IdGenerator idGenerator, UserBean ub)
			throws StockNoEnoughException, ParseException {
		InBill b = (InBill) inBillDao.get(InBill.class, id);
		if (b != null && b.getEnabled().equals("Y")) {
			b.setEnabled("N");
			b.setDisableManId(ub.getUser().getStafferId());
			b.setUpdateTime(new Date());
			inBillDao.update(b);
			if (b.getExamined().equals("Y")) {
				String log = PageHelper.getRequName(b.getOffererId(),
						b.getOffererType(), inBillDao);
				this.updateStock(b, inBillItemDao, stockDao, stockBalanceDao,
						idGenerator, log, "CANC", ub.getStaffer()
								.getStafferName());
			}

			if (b.getExamined().equals("Y")) {
				List arg15 = inBillItemDao.getList(b.getId());
				BigDecimal inCost = new BigDecimal(0);

				for (int j = 0; j < arg15.size(); ++j) {
					InBillItem item = (InBillItem) arg15.get(j);
					inCost = inCost.add(item.getCost());
				}

				this.updateBusinessProfit("SUB", b.getBusinessBillCode(),
						inCost, businessBillDao, idGenerator);
			}

			SystemLog arg16 = new SystemLog();
			arg16.setId(idGenerator.getId(SystemLog.class.getName()));
			arg16.setActionCode("IN_BILL");
			arg16.setLogType("CANCEL_LOG");
			arg16.setCreaterId(ub.getStaffer().getId());
			arg16.setCreaterName(ub.getStaffer().getStafferName());
			arg16.setDepName(ub.getDepName());
			arg16.setDepId(ub.getStaffer().getDepartmentId());
			arg16.setStatus("S");
			arg16.setUserName(ub.getUser().getUserName());
			arg16.setIp(b.getBillCode());
			arg16.setMark("");
			arg16.setRelId(id);
			arg16.setCancelReason(reason);
			arg16.setTallySetId(b.getTallySetId());
			inBillDao.save(arg16);
		}

	}
}